﻿using XYS.Core.Models;
using XYS.Service.Core.Service;

namespace XYS.Test.API;
/// <summary>
/// 分布式锁 key 帮助类
/// </summary>
public static class LockKeyHelper
{
    /// <summary>
    /// 加锁操作
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// 
    /// <param name="lockService"></param>
    /// <param name="lockKey"></param>
    /// <param name="actionAsync"></param>
    /// <returns></returns>
    public static ResultModel<T> AcquireLock<T>(this LockService lockService, string lockKey, Func<T> actionAsync)
    {
        using var @lock = lockService.CreateLockService(lockKey);
        bool lockFlag = @lock.Acquire;
        if (!lockFlag) return ResultModel<T>.Failed("锁资源未获取");

        try
        {
            var result = actionAsync();
            return ResultModel.Successed(result);
        }
        catch (Exception ex) { return ResultModel.Failed<T>(ex); }
    }


    /// <summary>
    /// 加锁操作
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// 
    /// <param name="lockService"></param>
    /// <param name="lockKey"></param>
    /// <param name="actionAsync"></param>
    /// <returns></returns>
    public static async Task<ResultModel<T>> AcquireLockAsync<T>(this LockService lockService, string lockKey, Func<Task<T>> actionAsync)
    {
        using var @lock = lockService.CreateLockService(lockKey);
        bool lockFlag = await @lock.AcquireAsync.ConfigureAwait(false);
        if (!lockFlag) return ResultModel<T>.Failed("锁资源未获取");

        try
        {
            var result = await actionAsync();
            return ResultModel.Successed(result);
        }
        catch (Exception ex) { return ResultModel.Failed<T>(ex); }
    }
    /// <summary>
    /// 加锁操作
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// 
    /// <param name="lockService"></param>
    /// <param name="lockKey"></param>
    /// <param name="taskTimeout">获取锁的超时时间</param>
    /// <param name="validTime">持有锁时间（默认1分钟）</param>
    /// <param name="actionAsync"></param>
    /// <returns></returns>
    public static async Task<ResultModel<T>> AcquireLockAsync<T>(this LockService lockService, string lockKey, TimeSpan taskTimeout, TimeSpan? validTime, Func<Task<T>> actionAsync)
    {
        if (validTime == null) validTime = TimeSpan.FromMinutes(1);
        using var @lock = lockService.CreateLockService(lockKey);
        bool lockFlag = await @lock.TakeAsync(taskTimeout, validTime).ConfigureAwait(false);
        if (!lockFlag) return ResultModel<T>.Failed("锁资源未获取");

        try
        {
            var result = await actionAsync().ConfigureAwait(false);
            return ResultModel.Successed(result);
        }
        catch (Exception ex) { return ResultModel.Failed<T>(ex); }
    }

    /// <summary>
    /// 提交前 签名
    /// </summary>
    /// <param name="signDataId"></param>
    /// <returns></returns>
    public static string SubmitFile(string signDataId) => $"lock:patent-file:submit-sign:{signDataId}";

    /// <summary>
    /// 创建发文对比
    /// </summary>
    /// <returns></returns>
    public static string CreateSendDocKey(string applicationNumber) => $"lock:online-detail:send-doc:create:{applicationNumber}";

    /// <summary>
    /// 释放客户端
    /// </summary>
    /// <returns></returns>
    public static string ClinetRelease() => $"lock:client:release";

    /// <summary>
    /// 文件绑定案卷
    /// </summary>
    /// <returns></returns>
    public static string PatentFileBindCase() => $"lock:patent-file:bind-case";

    /// <summary>
    /// 提交-执行提交
    /// </summary>
    /// <param name="clientId"></param>
    /// <returns></returns>
    public static string PatentFileSubmitCPCAccount(long clientId) => $"lock:patent-file:submit:{clientId}";

    /// <summary>
    /// 创建费用阶段
    /// </summary>
    /// <returns></returns>
    public static string CreateFeeTypeStage() => $"lock:fee-type-stage:create:all";

    /// <summary>
    /// 创建费用阶段
    /// </summary>
    /// <param name="feeTypeName"></param>
    /// <returns></returns>
    public static string CreateFeeTypeStage(string feeTypeName) => $"lock:fee-type-stage:create:{feeTypeName}";

    /// <summary>
    /// 创建费用类型
    /// </summary>
    /// <returns></returns>
    public static string CreateFeeType() => $"lock:fee-type:create:all";

    /// <summary>
    /// 创建费用类型
    /// </summary>
    /// <param name="feeTypeName"></param>
    /// <returns></returns>
    public static string CreateFeeType(string feeTypeName) => $"lock:fee-type:create:{feeTypeName}";

    /// <summary>
    /// 推送导入的通知书去解析 获取通知书列表
    /// </summary>
    /// <returns></returns>
    public static string PushNoticeInput() => "lock:notice:input:get-list";

    /// <summary>
    /// 预生成 第一步,绑定客户端
    /// </summary>
    /// <param name="orgId"></param>
    /// <returns></returns>
    public static string PatentFilePreviewBindClient(long orgId) => $"lock:patent-file:preview-check:{orgId}";
    /// <summary>
    /// 预生成-获取待预生成的文件
    /// </summary>
    /// <returns></returns>
    public static string PatentFilePreviewQuery() => "lock:patent-file:preview:query";
    /// <summary>
    /// 预生成-执行预生成
    /// </summary>
    /// <param name="clientId"></param>
    /// <returns></returns>
    public static string PatentFilePreviewCPCAccount(long clientId) => $"lock:patent-file:preview:{clientId}";
    /// <summary>
    /// 创建通知书
    /// </summary>
    /// <returns></returns>
    public static string CreateNotice() => "lock:notice:create";

    /// <summary>
    /// 从公海获取案卷
    /// </summary>
    /// <param name="orgId"></param>
    /// <returns></returns>
    public static string GetCaseByOpenSea(long orgId) => $"lock:case:get-by-open-sea:{orgId}";
    /// <summary>
    /// 获取国知局账号，用于同步通知书
    /// </summary>
    /// <param name="isConfirme">是否为已确认列表</param>
    /// <returns></returns>
    public static string GetAccountToSyncNotice(bool isConfirme) => $"lock:cpcaccount:notice-{(isConfirme ? "confirme" : "unconfirme")}";
    /// <summary>
    /// 获取国知局账号，用于同步证书
    /// </summary>
    /// <param name="isConfirme">是否为已确认列表</param>
    /// <returns></returns>
    public static string GetAccountToSyncCert(bool isConfirme) => $"lock:cpcaccount:cert-{(isConfirme ? "confirme" : "unconfirme")}";
    /// <summary>
    /// 获取用于检查状态的国知局账号
    /// </summary>
    /// <returns></returns>
    public static string GetAccountToCheck() => $"lock:cpcaccount:notice-check";


    /// <summary>
    /// 保存著录项目变更
    /// </summary>
    /// <param name="caseId"></param>
    /// <returns></returns>
    public static string SaveCaseRecordChanged(long caseId) => $"lock:case-record-change:{caseId}";

    /// <summary>
    /// 创建案卷
    /// </summary>
    /// <param name="applicationNumber">申请号</param>
    /// <returns></returns>
    public static string CreateCase(string applicationNumber) => $"lock:case:create:{applicationNumber}";

    /// <summary>
    /// 创建费用与组织关系
    /// </summary>
    /// <param name="FeeIds"></param>
    /// <returns></returns>
    public static string BingFeeOrg(List<long> FeeIds) => $"lock:org-fee:bind:{FeeIds}";

    /// <summary>
    /// 创建案卷与组织的关系
    /// </summary>
    /// <param name="caseId"></param>
    /// <returns></returns>
    public static string BindCaseOrg(long caseId) => $"lock:org-case:bind:{caseId}";

    /// <summary>
    /// 创建案卷与组织的关系
    /// </summary>
    /// <returns></returns>
    public static string BindCaseOrgALL() => $"lock:org-case:bind:Batch";
    /// <summary>
    /// 创建多国状态
    /// </summary>
    /// <returns></returns>
    public static string CreateOnlinePatentStatus() => "lock:online-status:create";
    /// <summary>
    /// 创建法律状态
    /// </summary>
    /// <returns></returns>
    public static string CreateLegalStatus() => "lock:online-status-legal:create";

    /// <summary>
    /// 获取用来同步列表的国知局账号
    /// </summary>
    /// <returns></returns>
    public static string GetSyncOnlineListCPCAccount() => "lock:cpcaccount:online-list";
    /// <summary>
    /// 获取用来同步明细的国知局账号
    /// </summary>
    /// <returns></returns>
    public static string GetSyncOnlineDetailCPCAccount() => "lock:cpcaccount:online-detail";
    /// <summary>
    /// 获取用来同步明细的申请号列表 内部
    /// </summary>
    /// <returns></returns>
    public static string GetSyncOnlineDetail() => "lock:case:online-detail";
    /// <summary>
    /// 获取用来同步明细的申请号列表 外部
    /// </summary>
    /// <returns></returns>
    public static string GetSyncOutsideOnlineDetail() => "lock:case:online-detail-outside";


    /// <summary>
    /// 预生成账号登录
    /// </summary>
    /// <param name="orgId"></param>
    /// <returns></returns>
    public static string PreviewQRLogin(long orgId) => $"lock:preview-qrlogin:{orgId}";
    /// <summary>
    /// 客户端绑定客户端
    /// </summary>
    /// <returns></returns>
    public static string BindClientByCPCAccount() => $"lock:client:bind-cpcaccount";

    /// <summary>
    /// 生成内部编号流水号
    /// </summary>
    /// <param name="orgId">分公司级别</param>
    /// <returns></returns>
    public static string GenerateInnerNumber(long orgId) => $"lock:inner_number:{orgId}";

    /// <summary>
    /// 获取一个用于导入的客户端
    /// </summary>
    /// <returns></returns>
    public static string GetClient2Import() => $"lock:client:get-import";

    /// <summary>
    /// 导入客户端
    /// </summary>
    /// <param name="clientId"></param>
    /// <returns></returns>
    public static string ImportCase2Clinet(long clientId) => $"lock:client:import:{clientId}";

    /// <summary>
    /// 设置组织下未设置流水号的专利
    /// </summary>
    /// <param name="orgId"></param>
    /// <returns></returns>
    public static string SetInnerNumberSerialNumber(long orgId) => $"lock:patent-file:serialnumber:{orgId}";

    /// <summary>
    /// 解析cpc案卷包内容
    /// </summary>
    /// <returns></returns>
    public static string UnpackPatentFile() => "lock:patent-file:unpack";

    /// <summary>
    /// 发送发件箱邮件
    /// </summary>
    /// <returns></returns>
    public static string SendOutboxEmail() => "lock:send-outbox-email:send";

    /// <summary>
    /// 获取客户端列表
    /// </summary>
    /// <returns></returns>
    public static string GetCPCClientList() => $"lock:cpc_client:getcpcclientlist";

    /// <summary>
    /// 更新客户端状态
    /// </summary>
    /// <returns></returns>
    public static string BatchUpdatetCPCClientState() => $"lock:cpc_client:batchupdatecpcclientstate";
}